package com.gae.blore.client;

import java.util.List;

import com.gae.blore.client.dialog.ErrorDialog;
import com.gae.blore.client.dialog.LoadingWidget;
import com.gae.blore.client.domain.BusStop;
import com.gae.blore.client.domain.FireBrigadeStation;
import com.gae.blore.client.domain.Hospital;
import com.gae.blore.client.domain.MetroStation;
import com.gae.blore.client.domain.PoliceStation;
import com.gae.blore.client.domain.RailwayStation;
import com.gae.blore.client.map.NetworkMap;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class BangloreInfo implements EntryPoint {

	private final NetworkMap networkMap = new NetworkMap();
	private LoadingWidget loadingWidget = new LoadingWidget();

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		String news = "<iframe src=\"http://www.google.com/uds/modules/elements/newsshow/iframe.html?format=300x250&q=Bangalore\" frameborder=\"0\" width=\"300\" height=\"250\" marginwidth=\"0\" marginheight=\"0\"></iframe>";
		// Wrap the split panel in a decorator panel
		DockPanel decPanel = new DockPanel();

		decPanel.setWidth("100%");
		decPanel.setHeight("100%");
		// decPanel.add(createToolbar(), DockPanel.NORTH);
		decPanel.setStyleName("bg-Color");

		VerticalPanel newsPanel = new VerticalPanel();
		HTML newsHeader = new HTML("Bangalore News");
		newsHeader.setStyleName("news-header");
		HTML html = new HTML();
		html.setHTML(news);
		newsPanel.add(newsHeader);
		newsPanel.add(html);
		newsPanel.setStyleName("vertical-toolbar");
		VerticalPanel eastPanel = new VerticalPanel();
		eastPanel.add(newsPanel);
		decPanel.add(networkMap.getNetworkMap(), DockPanel.CENTER);
		networkMap.getNetworkMap().add(createToolbar(), DockPanel.NORTH);
		decPanel.add(eastPanel, DockPanel.EAST);
		RootPanel.get("main").add(decPanel);
		networkMap.init();

	}

	private void loadBusStops() {
		final BusStopServiceAsync busStopService = GWT
				.create(BusStopService.class);
		showLoading();
		busStopService.getAllBusStops(new AsyncCallback<List<BusStop>>() {

			@Override
			public void onSuccess(List<BusStop> result) {
				networkMap.getFeatureLayer().addBusStopsToMap(result);
				stopLoading();
			}

			@Override
			public void onFailure(Throwable caught) {
				stopLoading();
				handleError();

			}
		});

	}

	private void unloadBusStops() {
		networkMap.getFeatureLayer().clearBusStopsFromMap();

	}

	private void loadPoliceStations() {
		final PoliceStationServiceAsync policeStationServiceAsync = GWT
				.create(PoliceStationService.class);
		showLoading();
		policeStationServiceAsync
				.getAllPoliceStation(new AsyncCallback<List<PoliceStation>>() {

					@Override
					public void onSuccess(List<PoliceStation> result) {

						networkMap.getFeatureLayer().addPoliceStationsToMap(
								result);
						stopLoading();
					}

					@Override
					public void onFailure(Throwable caught) {
						stopLoading();
						handleError();

					}
				});
	}

	private void unLoadPoliceStations() {
		networkMap.getFeatureLayer().clearPoliceStations();
	}

	private void loadHospitals() {

		final HospitalServiceAsync hospitalServiceAsync = GWT
				.create(HospitalService.class);
		showLoading();
		hospitalServiceAsync
				.getAllHospitals(new AsyncCallback<List<Hospital>>() {

					@Override
					public void onSuccess(List<Hospital> result) {

						networkMap.getFeatureLayer().addHospitalsToMap(result);
						stopLoading();
					}

					@Override
					public void onFailure(Throwable caught) {
						stopLoading();
						handleError();

					}
				});
	}

	private void unLoadHospitals() {
		networkMap.getFeatureLayer().clearHospitalsFromMap();
	}

	private void loadMetroStations() {

		final MetroStationServiceAsync metroServiceAsync = GWT
				.create(MetroStationService.class);
		showLoading();
		metroServiceAsync
				.getAllMetroStations(new AsyncCallback<List<MetroStation>>() {

					public void onFailure(Throwable caught) {
						stopLoading();
						handleError();

					}

					public void onSuccess(List<MetroStation> result) {
						networkMap.getFeatureLayer().addMetroStationToMap(
								result);
						stopLoading();
					}
				});

	}

	private void unLoadMetroStations() {
		networkMap.getFeatureLayer().clearMetroStations();
	}

	private void loadRailStations() {
		final RailwayStationServiceAsync railServiceAsync = GWT
				.create(RailwayStationService.class);
		showLoading();
		railServiceAsync
				.getAllRailwayStations(new AsyncCallback<List<RailwayStation>>() {

					public void onFailure(Throwable caught) {
						stopLoading();
						handleError();

					}

					public void onSuccess(List<RailwayStation> result) {
						networkMap.getFeatureLayer().addRailwayStationToMap(
								result);
						stopLoading();

					}
				});

	}

	private void unLoadRailStations() {
		networkMap.getFeatureLayer().clearRailStations();
	}

	private void loadFireStations() {
		final FireBrigateStationServiceAsync fireBrigadeService = GWT
				.create(FireBrigateStationService.class);
		showLoading();
		fireBrigadeService
				.getAllFireBrigadeStations(new AsyncCallback<List<FireBrigadeStation>>() {

					public void onFailure(Throwable caught) {
						stopLoading();
						handleError();

					}

					public void onSuccess(List<FireBrigadeStation> result) {
						networkMap.getFeatureLayer()
								.addFireBrigadeStationToMap(result);
						stopLoading();
					}
				});

	}

	private void unLoadFireStations() {
		networkMap.getFeatureLayer().clearFireBrigadeStations();
	}

	private Widget createToolbar() {

		HorizontalPanel verticalPanel = new HorizontalPanel();
		ValueChangeHandler<Boolean> busHandler = new BusStopsHandler();
		ValueChangeHandler<Boolean> hospHandler = new HospitalsHandler();
		ValueChangeHandler<Boolean> polHandler = new PoliceStationsHandler();
		ValueChangeHandler<Boolean> fireHandler = new FireHandler();
		ValueChangeHandler<Boolean> railHandler = new RailHandler();
		ValueChangeHandler<Boolean> metroHandler = new MetroHandler();

		Widget busGrid = createToolbarMenu("Bus Stops", "images/bus.jpg",
				busHandler);
		Widget hospGrid = createToolbarMenu("Hospitals", "images/hosp.jpg",
				hospHandler);

		Widget metroGrid = createToolbarMenu("Metro Stops", "images/metro.jpg",
				metroHandler);
		Widget railGrid = createToolbarMenu("Railway Stations",
				"images/rail.jpg", railHandler);
		Widget polGrid = createToolbarMenu("Police Stations",
				"images/police.jpg", polHandler);
		Widget fireGrid = createToolbarMenu("Fire Brigade", "images/fire.jpg",
				fireHandler);

		verticalPanel.add(busGrid);
		verticalPanel.add(railGrid);
		verticalPanel.add(metroGrid);
		verticalPanel.add(polGrid);
		verticalPanel.add(fireGrid);
		verticalPanel.add(hospGrid);

		verticalPanel.setStyleName("vertical-toolbar");
		return verticalPanel;
	}

	private Widget createToolbarMenu(String label, String graphic,
			ValueChangeHandler<Boolean> handler) {
		CheckBox checkBox = new CheckBox();
		HTML menuLabel = new HTML(label);
		Image image = new Image(graphic);

		checkBox.addValueChangeHandler(handler);

		FlexTable flexTable = new FlexTable();
		flexTable.setWidget(0, 0, checkBox);
		flexTable.setWidget(0, 1, image);
		flexTable.setWidget(0, 2, menuLabel);

		return flexTable;

	}

	private class BusStopsHandler implements ValueChangeHandler<Boolean> {

		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {
			boolean isSelected = event.getValue();
			if (isSelected) {
				loadBusStops();
			} else {
				unloadBusStops();
			}

		}

	}

	private class HospitalsHandler implements ValueChangeHandler<Boolean> {

		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {

			boolean isSelected = event.getValue();
			if (isSelected) {
				loadHospitals();
			} else {
				unLoadHospitals();
			}

		}

	}

	private class MetroHandler implements ValueChangeHandler<Boolean> {

		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {

			boolean isSelected = event.getValue();
			if (isSelected) {
				loadMetroStations();
			} else {
				unLoadMetroStations();
			}

		}

	}

	private class PoliceStationsHandler implements ValueChangeHandler<Boolean> {

		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {
			boolean isSelected = event.getValue();
			if (isSelected) {
				loadPoliceStations();
			} else {
				unLoadPoliceStations();
			}

		}

	}

	private class FireHandler implements ValueChangeHandler<Boolean> {

		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {

			boolean isSelected = event.getValue();
			if (isSelected) {
				loadFireStations();
			} else {
				unLoadFireStations();
			}

		}

	}

	private class RailHandler implements ValueChangeHandler<Boolean> {

		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {

			boolean isSelected = event.getValue();
			if (isSelected) {
				loadRailStations();
			} else {
				unLoadRailStations();
			}

		}

	}

	private void handleError() {
		ErrorDialog errorDialog = new ErrorDialog();
		errorDialog.center();

	}

	private void showLoading() {
		loadingWidget.setPopupPosition(420, 410);
		loadingWidget.startProcessing();
	}

	private void stopLoading() {
		loadingWidget.stopProcessing();
	}

}
